﻿using System;
using System.Collections.Generic;

namespace Mars.GpuInstance
{
    public class InstanceCacheDataManager : IDisposable
    {
        private static InstanceCacheDataManager instance;

        public static InstanceCacheDataManager GetInstance()
        {
#if UNITY_EDITOR
            if (instance == null)
#else
            if (instance is null)
#endif
            {
                instance = new InstanceCacheDataManager();
                //instance.Test();
            }

            return instance;
        }
        
        private Queue<InstanceRuntimeData> freeInstanceRuntimeDataList = new (50);
        private Queue<InstanceRenderBatch> freeInstanceRenderBatchList = new (100);

        public void Tick()
        {
            ReleaseInstanceRuntimeData();
            ReleaseInstanceRenderBatch();
        }

        public InstanceRuntimeData GetInstanceRuntimeData()
        {
            var count = freeInstanceRuntimeDataList.Count;
            if (count > 0)
            {
                var freeItem = freeInstanceRuntimeDataList.Dequeue();
                freeItem.InitContainer();
                return freeItem;
            }

            var item = new InstanceRuntimeData();
            return item;
        }
        
        public void ReturnInstanceRuntimeData(InstanceRuntimeData instanceRuntimeData)
        {
            instanceRuntimeData.OnRecycle();
            freeInstanceRuntimeDataList.Enqueue(instanceRuntimeData);
        }

        public InstanceRenderBatch GetInstanceRenderBatch()
        {
            var count = freeInstanceRenderBatchList.Count;
            if (count > 0)
            {
                return freeInstanceRenderBatchList.Dequeue();
            }

            var item = new InstanceRenderBatch();
            return item;
        }

        public void ReturnInstanceRenderBatch(InstanceRenderBatch batch)
        {
  
                batch.OnRecycle();
                freeInstanceRenderBatchList.Enqueue(batch);
            
        }




        #region 释放相关

        private void ReleaseInstanceRuntimeData()
        {
            var count = freeInstanceRuntimeDataList.Count;
            if (count > 0)
            {
                var item = freeInstanceRuntimeDataList.Dequeue();
                item.Dispose();
            }
        }
        
        private void ReleaseInstanceRenderBatch()
        {
            var count = freeInstanceRenderBatchList.Count;
            if (count > 0)
            {
                var item = freeInstanceRenderBatchList.Dequeue();
                item.Dispose();
            }
        }



        #endregion
        
        public void Dispose()
        {
            Clear();
        }

        public void Clear()
        {
            foreach (var instanceRuntimeData in freeInstanceRuntimeDataList)
            {
                instanceRuntimeData.Dispose();
            }
            foreach (var batch in freeInstanceRenderBatchList)
            {
                batch.Dispose();
            }
            
            freeInstanceRuntimeDataList.Clear();
            freeInstanceRenderBatchList.Clear();
        }
    }
}